(* Copyright (C) 2010 School of Software Engineering, 
 * University of Science and Technology of China.
 *
 * This code is released under a BSD-style license.
 * See the file LICENSE for details.
 *)

structure Main = 
struct 

structure ByteCode = ByteCode ()
structure Parser = Parser (structure ByteCode = ByteCode)
structure Jvm = Jvm (structure ByteCode = ByteCode)

fun main2 fileName =
    let val v = Control.L2
        val input = 
            Control.pass {v = v,
                          name = "readFile",
                          action = fn _ => FileReader.readFile fileName,
                          display = fn _ => Layout.empty ()}
	val program = 
            Control.pass {v = v,
                          name = "parse",
                          action = fn _ => Parser.parseCode input,
                          display = ByteCode.CodeHeap.layout}
	val result = 
            Control.pass {v = v,
                          name = "virtual machine",
                          action = fn _ => Jvm.run program,
                          display = Layout.str o Int.toString}
    in  print (String.concat ["Result:", 
                              Int.toString result, 
                              "\n"])
    end
    
fun main () =
    let fun usage () = print (String.concat ["jvm: a minimal JVM",
                                             "\n",
                                             "Usage: jvm file.class\n"])
        val args = CommandLine.arguments ()
        val args = CommandArg.cook (args)
    in  case args 
         of CommandArg.Yes [] => usage ()
          | CommandArg.Yes [f] => 
            (Control.fileName := f
           ; Control.trace (Control.L1, "jvm", main2) f)
          | CommandArg.Yes _ => 
            (print "too many files\n"
           ; usage ())
          | _ => ()
    end

end
